package com.yifushidai.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.util.matcher.RequestMatcher;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * springsecurity配置了csrf()，csrf会拦截所有的post请求，这涉及到csrf攻击
 * https://bbs.csdn.net/topics/392172607
 */
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String[] AUTH_WHITELIST = {
            // -- swagger ui
            "/doc.html",
            "/swagger-ui.html",
            "/swagger-resources/**",
            "/v2/api-docs",
            "/webjars/**"
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                // swagger页面需要添加登录校验
//                .antMatchers("/swagger-ui.html").authenticated()
                .antMatchers(AUTH_WHITELIST).authenticated()
                //普通的接口不需要校验
//                .antMatchers("/app/**").permitAll()
//                .antMatchers("/web/**").permitAll()
                .anyRequest().permitAll()
                .and()
                .csrf().disable()
//                .csrf().requireCsrfProtectionMatcher(new CsrfSecurityRequestMatcher())
//                .and()
                .formLogin();
    }

    class CsrfSecurityRequestMatcher implements RequestMatcher {
        private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");

        @Override
        public boolean matches(HttpServletRequest request) {
            List<String> execludeUrls = new ArrayList<>();
            execludeUrls.add("/api");//允许post请求的url路径，这只是简单测试，具体要怎么设计这个csrf处理，看个人爱好

            if (!execludeUrls.isEmpty()) {
                String servletPath = request.getServletPath();
                for (String url : execludeUrls) {
                    if (servletPath.contains(url)) {
                        return false;
                    }
                }
            }
            return !allowedMethods.matcher(request.getMethod()).matches();
        }
    }
}